package cn.itcast.service.cargo.impl;

import cn.itcast.dao.cargo.*;
import cn.itcast.domain.cargo.*;
import cn.itcast.service.cargo.ExportService;
import cn.itcast.vo.ExportProductResult;
import cn.itcast.vo.ExportResult;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

@Service
public class ExportServiceImpl implements ExportService {

    @Autowired
    private ExportDao exportDao;

    @Autowired
    private ContractDao contractDao;

    @Autowired
    private ContractProductDao contractProductDao;

    @Autowired
    private ExportProductDao exportProductDao;

    @Autowired
    private ExtCproductDao extCproductDao;

    @Autowired
    private ExtEproductDao extEproductDao;

    //保存
    public void save(Export export) {
        //修改合同的状态
            //1.1获取合同的id
        String contractIds = export.getContractIds();
            //1.2切割每一个合同id
        String[] contractIdsArr = contractIds.split(",");
            //1.3循环遍历合同id获取每一个合同
        StringBuffer buffer = new StringBuffer();
        for (String contractId : contractIdsArr) {
            //1.4获取合同，修改合同状态
            Contract contract = contractDao.selectByPrimaryKey(contractId);
            //状态2为已报运
            contract.setState(2);
            //1.5记录每一个合同的合同号（合同号之间空格隔开）
            buffer.append(contract.getContractNo()).append(" ");
            //1.6修改合同
            contractDao.updateByPrimaryKeySelective(contract);
        }

        //2保存报运单数据（手动设置id合同号  状态  时间）
        //主键
        export.setId(UUID.randomUUID().toString().replace("-",""));
        //合同号
        export.setCustomerContract(buffer.toString());
        //状态  0：草稿
        export.setState(0);
        //生成报运单的时间
        export.setCreateTime(new Date());
        //3保存货物数据（来源于合同的货物数据）
            //3.1根据合同的id获取数据
        ContractProductExample contractProductExample = new ContractProductExample();
        ContractProductExample.Criteria contractProductExampleCriteria = contractProductExample.createCriteria();
            //3.2将数组转换成集合，根据条件合同id的集合查询合同下的货物
        List<String> ContractIdsList = Arrays.asList(contractIdsArr);
        contractProductExampleCriteria.andContractIdIn(ContractIdsList);
        //根据合同id查合同下的货物
        List<ContractProduct> productList = contractProductDao.selectByExample(contractProductExample);
            //3.3遍历循环合同货物
                //合同的货物==报运单的货物
                //记录合同的货物id==报运单的货物id  map<合同货物的id,报运单的货物id>
        HashMap<String, String> map = new HashMap<>();
        for(ContractProduct contractProduct:productList){
            //3.4循环一个合同货物创建一个报运单货物
            ExportProduct exportProduct = new ExportProduct();
            //3.5将合同的每一个货物数据给报运单的每一个货物
            BeanUtils.copyProperties(contractProduct,exportProduct);
            //3.6设置报运单的唯一主键
            exportProduct.setId(UUID.randomUUID().toString().replace("-",""));
            //3.7设置货物属于哪一个报运单
            exportProduct.setExportId(export.getId());
            //3.8保存每一个报运单的货物
            exportProductDao.insertSelective(exportProduct);
            //3.9记录合同的货物id和报运单的货物id
            //key:合同的货物id   value:报运单的货物id
            map.put(contractProduct.getId(),exportProduct.getId());

        }

        //4.保存附件数据（来源于合同的货物附件）
            //4.1根据合同的id获取合同的附件
        ExtCproductExample extCproductExample = new ExtCproductExample();
        ExtCproductExample.Criteria extCproductExampleCriteria = extCproductExample.createCriteria();
        //ContractIdsList  合同的id
        extCproductExampleCriteria.andContractIdIn(ContractIdsList);
        // ExtCproduct 合同下货物的附件
        List<ExtCproduct> extCproductList = extCproductDao.selectByExample(extCproductExample);
            //4.2遍历循环合同下的附件（附件有货物id)map.get(extCproduct.getContractProductId(合同的货物id））
        for (ExtCproduct extCproduct : extCproductList) {
            //4.3有一个合同的附件就有一个报运单的附近  ExtEproduct:报运单中货物附件的实体类
            ExtEproduct extEproduct = new ExtEproduct();
            //4.4将合同的附件数据给报运单的附件数据   extCproduct:合同下货物的附件
            BeanUtils.copyProperties(extCproduct,extEproduct);
            //4.5设置报运单的附件主键
            extEproduct.setId(UUID.randomUUID().toString().replace("-",""));
            //4.6设置报运单的附件属于哪个货物id   ExportProductId:附件和货物，多对一:
            extEproduct.setExportProductId(map.get(extCproduct.getContractProductId()));
            //4.7设置报运单的附件属于哪个报运单id   Export:报运表
            extEproduct.setExportId(export.getId());
            //4.8保存附件
            extEproductDao.insertSelective(extEproduct);

        }
        //5设置报运单的货物数/附件数
        export.setProNum(productList.size());
        export.setExtNum(extCproductList.size());
        //6保存报运单
        exportDao.insertSelective(export);

    }

    //修改
    public void update(Export export) {
        //1修改报运单的数据
        exportDao.updateByPrimaryKeySelective(export);
        //修改报运单下货物的数据
        List<ExportProduct> list = export.getExportProducts();
        for (ExportProduct exportProduct : list) {
            exportProductDao.updateByPrimaryKeySelective(exportProduct);
        }
    }

    //报运单的分页查询
    public PageInfo findAll(ExportExample exportExample, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<Export> exports = exportDao.selectByExample(exportExample);
        PageInfo<Export> pageInfo = new PageInfo<>(exports);
        return pageInfo;
    }

    //通过id查询报运单
    public Export findById(String id) {
        return exportDao.selectByPrimaryKey(id);
    }

    //带着报运单的id进行删除
    public void delete(String id) {
        //删除报运单
        exportDao.deleteByPrimaryKey(id);
        //删除报运单下的货物
            //根据报运单的id获取货物集合
        ExportProductExample exportProductExample = new ExportProductExample();
        ExportProductExample.Criteria criteria = exportProductExample.createCriteria();
        criteria.andExportIdEqualTo(id);
        List<ExportProduct> productList = exportProductDao.selectByExample(exportProductExample);
        //遍历循环删除每一个货物
        for (ExportProduct exportProduct : productList) {
            exportProductDao.deleteByPrimaryKey(exportProduct.getId());
        }
        //删除报运单下的货物附件
            //根据报运单的id货物货物附件集合
        ExtEproductExample extEproductExample = new ExtEproductExample();
        ExtEproductExample.Criteria extEproductExampleCriteria = extEproductExample.createCriteria();
        extEproductExampleCriteria.andExportIdEqualTo(id);
        List<ExtEproduct> extEproductList = extEproductDao.selectByExample(extEproductExample);
        //遍历循环删除每一个货物
        for (ExtEproduct extEproduct : extEproductList) {
            extEproductDao.deleteByPrimaryKey(extEproduct.getId());
        }
    }

    //修改自己的报运单数据（状态和备注）以及报运单的货物数据（税）
    public void updateByResult(ExportResult exportResult) {  //  ExportResult  export
        //修改报运单
        //1根据报运单的id获取报运单   报运表Export
        Export export = exportDao.selectByPrimaryKey(exportResult.getExportId());
        //2.设置报运单的属性
        //设置报运单的状态
        export.setState(exportResult.getState());
        //设置报运单的备注
        export.setRemark(exportResult.getRemark());
        //3.修改报运单
        exportDao.updateByPrimaryKeySelective(export);
        //修改报运单下的货物
        //1.获取报运单的货物集合
        if (exportResult.getProducts()!=null){
            for (ExportProductResult productResult : exportResult.getProducts()) {   //  ExportProductResult(货物)  products   exportResult.getProducts():保运表下的货物
                //2.获取到报运单下的货物
                ExportProduct exportProduct = exportProductDao.selectByPrimaryKey(productResult.getExportProductId());
                //3.修改货物的税
                exportProduct.setTax(productResult.getTax());
                //4.修改每一个货物
                exportProductDao.updateByPrimaryKeySelective(exportProduct);
            }
        }
    }

    /*@Override
    public void updateState(String id) {
        Export export = exportDao.selectByPrimaryKey(id);
        export.setState(3);
        exportDao.updateByPrimaryKeySelective(export);
    }*/
    public void updateState(Export export) {
        exportDao.updateByPrimaryKeySelective(export);
    }

   /* public void updateStatePacking(String exportId) {
        Export export = exportDao.selectByPrimaryKey(exportId);
        export.setState(3);
        exportDao.updateByPrimaryKeySelective(export);
    }*/
}
